package com.ss.ugc.android.alpha_player.utils;

import com.ss.ugc.android.alpha_player.model.ScaleType;

/**
 * 优化版纹理裁剪工具类
 * 支持功能：
 * 1. 左右/上下分屏动态切换
 * 2. 兼容全部ScaleType缩放模式
 * 3. 顶点数据复用避免重复计算
 * created by dengzhuoyao on 2020/07/07
 * optimized on 2025/06/17
 */
public class TextureCropUtil {

    /** 分屏方向枚举 */
    public enum SplitDirection {
        HORIZONTAL, // 左右分屏（右半部分）
        VERTICAL    // 上下分屏（上半部分）
    }

    /**
     * 核心方法：计算分屏顶点数据
     * @param direction 分屏方向（HORIZONTAL/VERTICAL）
     * @param scaleType 缩放模式
     * @param viewWidth 视图宽度
     * @param viewHeight 视图高度
     * @param videoWidth 视频原始宽度
     * @param videoHeight 视频原始高度
     * @return 顶点数组（4个顶点 * XYZUV共20个float）
     */
    public static float[] calculateSplitVerticeData(SplitDirection direction,
                                                    ScaleType scaleType,
                                                    float viewWidth, float viewHeight,
                                                    float videoWidth, float videoHeight) {
        // 1. 计算基础顶点（未分屏的完整UV范围）
        float[] baseVertices = calculateBaseVertices(scaleType, viewWidth, viewHeight, videoWidth, videoHeight);

        // 2. 根据方向调整UV坐标
        return (direction == SplitDirection.VERTICAL) ?
                adjustForVerticalSplit(baseVertices) :
                adjustForHorizontalSplit(baseVertices);
    }

    // region 私有方法
    /**
     * 计算基础顶点数据（未分屏的完整UV范围）
     */
    private static float[] calculateBaseVertices(ScaleType scaleType,
                                                 float viewWidth, float viewHeight,
                                                 float videoWidth, float videoHeight) {
        float[] result;
        float currentRatio = viewWidth / viewHeight;
        float videoRatio = videoWidth / videoHeight;
        float ratioX, ratioY;

        // 根据宽高比决定裁剪策略（与原逻辑一致）
        if (currentRatio > videoRatio) {
            videoWidth = viewWidth;
            videoHeight = videoWidth / videoRatio;
            ratioX = 0;
            ratioY = (1 - (viewHeight / videoHeight)) / 2;
        } else {
            videoHeight = viewHeight;
            videoWidth = videoHeight * videoRatio;
            ratioX = (1 - (viewWidth / videoWidth)) / 2;
            ratioY = 0;
        }

        // 处理不同ScaleType模式
        switch (scaleType) {
            case ScaleAspectFitCenter:
                if (currentRatio > videoRatio) {
                    videoHeight = viewHeight;
                    videoWidth = videoHeight * videoRatio;
                    ratioX = (1 - (videoWidth / viewWidth)) / 2;
                    ratioY = 0;
                } else {
                    videoWidth = viewWidth;
                    videoHeight = videoWidth / videoRatio;
                    ratioX = 0;
                    ratioY = (1 - (videoHeight / viewHeight)) / 2;
                }
                result = getZoomData(ratioX, ratioY, ratioX, ratioY);
                break;
            case ScaleAspectFill:
                result = getCropData(ratioX, ratioY, ratioX, ratioY);
                break;
            case TopFill:
                result = getCropData(ratioX, 0, ratioX, ratioY * 2);
                break;
            case BottomFill:
                result = getCropData(ratioX, ratioY * 2, ratioX, 0);
                break;
            case LeftFill:
                result = getCropData(0, ratioY, ratioX * 2, ratioY);
                break;
            case RightFill:
                result = getCropData(ratioX * 2, ratioY, 0, ratioY);
                break;
            case TopFit:
                videoWidth = viewWidth;
                videoHeight = videoWidth / videoRatio;
                ratioY = (1 - (videoHeight / viewHeight)) / 2;
                result = getZoomData(0, 0, 0, ratioY * 2);
                break;
            case BottomFit:
                videoWidth = viewWidth;
                videoHeight = videoWidth / videoRatio;
                ratioY = (1 - (videoHeight / viewHeight)) / 2;
                result = getZoomData(0, ratioY * 2, 0, 0);
                break;
            case LeftFit:
                videoHeight = viewHeight;
                videoWidth = videoHeight * videoRatio;
                ratioX = (1 - (videoWidth / viewWidth)) / 2;
                result = getZoomData(0, 0, ratioX * 2, 0);
                break;
            case RightFit:
                videoHeight = viewHeight;
                videoWidth = videoHeight * videoRatio;
                ratioX = (1 - (videoWidth / viewWidth)) / 2;
                result = getZoomData(ratioX * 2, 0, 0, 0);
                break;
            default: // 全屏拉伸
                result = getCropData(0, 0, 0, 0);
        }
        result = getCropData(0, 0, 0, 0);

        return result;
    }

    /** 上下分屏：压缩V坐标到0-0.5范围（上半部分） */
    private static float[] adjustForVerticalSplit(float[] vertices) {
        for (int i = 4; i < vertices.length; i += 5) {
            vertices[i] *= 0.5f;
        }
        return vertices;
    }

    /** 左右分屏：压缩U坐标到0.5-1范围（右半部分） */
    private static float[] adjustForHorizontalSplit(float[] vertices) {
        for (int i = 3; i < vertices.length; i += 5) {
            vertices[i] = 0.5f + vertices[i] * 0.5f;
        }
        return vertices;
    }

    /** 生成缩放模式顶点数据（修正初始UV） */
    private static float[] getZoomData(float leftZoom, float topZoom, float rightZoom, float bottomZoom) {
        return new float[]{
                -1.0f + leftZoom * 2, -1.0f + bottomZoom * 2, 0, 0.0f, 0.0f,  // 改为从0开始
                1.0f - rightZoom * 2, -1.0f + bottomZoom * 2, 0, 1.0f, 0.0f,
                -1.0f + leftZoom * 2, 1.0f - topZoom * 2, 0, 0.0f, 1.0f,
                1.0f - rightZoom * 2, 1.0f - topZoom * 2, 0, 1.0f, 1.0f
        };
    }

    /** 生成裁剪模式顶点数据（修正初始UV）
     *
     *  0.0f, -1.0f, 0f, 0.5f, 0f,
     *             1.0f, -1.0f, 0f, 1f, 0f,
     *             0.0f, 1.0f, 0f, 0.5f, 1f,
     *             1.0f, 1.0f, 0f, 1f, 1f
     *             */
    private static float[] getCropData(float leftCrop, float topCrop, float rightCrop, float bottomCrop) {
        return new float[]{
                -1f, -1f, 0, leftCrop, bottomCrop,
                1f, -1f, 0, 1f-rightCrop, bottomCrop,
                -1f, 1f, 0, leftCrop, 1f-topCrop,
                1f, 1f, 0, 1f-rightCrop, 1f-topCrop
        };
    }

    // endregion
}
